"""RPA框架任务管理组件"""

import time
from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, 
    QGroupBox, QTableWidget, QTableWidgetItem, QHeaderView,
    QComboBox, QDateTimeEdit, QMessageBox, QMenu, QAction,
    QDialog, QLineEdit, QTextEdit, QSpinBox, QDialogButtonBox, 
    QFormLayout, QFrame
)
from PyQt5.QtCore import Qt, pyqtSignal, QDateTime
from PyQt5.QtGui import QFont, QColor, QCursor

from rpa_framework.core.task import Task, TaskStatus
# 使用标准logging模块
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger("rpa.gui.task_manager")


class TaskEditDialog(QDialog):
    """任务编辑对话框"""
    
    def __init__(self, task, parent=None):
        """初始化编辑对话框
        
        Args:
            task: 要编辑的任务对象
            parent: 父窗口
        """
        super().__init__(parent)
        self.task = task
        self.init_ui()
    
    def init_ui(self):
        """初始化用户界面"""
        self.setWindowTitle("编辑任务")
        self.setMinimumWidth(400)
        
        # 创建布局
        main_layout = QVBoxLayout(self)
        
        # 表单布局
        form_layout = QFormLayout()
        
        # 任务ID（只读）
        self.id_edit = QLineEdit(self.task.id)
        self.id_edit.setReadOnly(True)
        form_layout.addRow("任务ID:", self.id_edit)
        
        # 任务名称
        self.name_edit = QLineEdit(self.task.name)
        form_layout.addRow("任务名称:", self.name_edit)
        
        # 任务描述
        self.description_edit = QTextEdit(self.task.description)
        self.description_edit.setMinimumHeight(80)
        form_layout.addRow("任务描述:", self.description_edit)
        
        # 超时时间（秒）
        self.timeout_spin = QSpinBox()
        self.timeout_spin.setRange(0, 3600)  # 0表示无超时
        self.timeout_spin.setValue(self.task.timeout if self.task.timeout else 0)
        self.timeout_spin.setSuffix(" 秒 (0表示无超时)")
        form_layout.addRow("超时时间:", self.timeout_spin)
        
        # 添加表单到主布局
        main_layout.addLayout(form_layout)
        
        # 添加分割线
        separator = QFrame()
        separator.setFrameShape(QFrame.HLine)
        separator.setFrameShadow(QFrame.Sunken)
        main_layout.addWidget(separator)
        
        # 按钮
        buttons = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Cancel)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        main_layout.addWidget(buttons)
    
    def get_updated_task_data(self):
        """获取更新后的任务数据
        
        Returns:
            更新后的任务数据字典
        """
        timeout = self.timeout_spin.value()
        timeout = timeout if timeout > 0 else None
        
        return {
            'name': self.name_edit.text(),
            'description': self.description_edit.toPlainText(),
            'timeout': timeout
        }

class TaskManagerWidget(QWidget):
    """任务管理组件"""
    
    # 定义信号
    task_selected = pyqtSignal(Task)
    task_added = pyqtSignal(Task)
    task_removed = pyqtSignal(str)  # task_id
    task_execution_requested = pyqtSignal(str)  # task_id
    
    def __init__(self):
        super().__init__()
        
        # 任务列表
        self._tasks = {}
        
        # 初始化UI
        self._init_ui()
    
    def _init_ui(self):
        """初始化UI组件"""
        main_layout = QVBoxLayout(self)
        
        # 工具栏
        toolbar_layout = QHBoxLayout()
        
        # 添加任务按钮
        self.add_task_button = QPushButton("添加任务")
        self.add_task_button.setToolTip("添加新的RPA任务")
        self.add_task_button.clicked.connect(self.add_new_task)
        toolbar_layout.addWidget(self.add_task_button)
        
        # 编辑任务按钮
        self.edit_task_button = QPushButton("编辑任务")
        self.edit_task_button.setToolTip("编辑选中的任务")
        self.edit_task_button.clicked.connect(self.edit_selected_task)
        self.edit_task_button.setEnabled(False)
        toolbar_layout.addWidget(self.edit_task_button)
        
        # 删除任务按钮
        self.delete_task_button = QPushButton("删除任务")
        self.delete_task_button.setToolTip("删除选中的任务")
        self.delete_task_button.clicked.connect(self.delete_selected_task)
        self.delete_task_button.setEnabled(False)
        toolbar_layout.addWidget(self.delete_task_button)
        
        # 执行任务按钮
        self.execute_task_button = QPushButton("执行任务")
        self.execute_task_button.setToolTip("立即执行选中的任务")
        self.execute_task_button.clicked.connect(self.execute_selected_task)
        self.execute_task_button.setEnabled(False)
        toolbar_layout.addWidget(self.execute_task_button)
        
        # 添加分隔符
        toolbar_layout.addStretch()
        
        # 筛选下拉框
        self.filter_combo = QComboBox()
        self.filter_combo.addItems(["全部任务", "已完成", "执行中", "未开始", "已失败", "已暂停"])
        self.filter_combo.currentTextChanged.connect(self.filter_tasks)
        toolbar_layout.addWidget(QLabel("筛选:"))
        toolbar_layout.addWidget(self.filter_combo)
        
        # 刷新按钮
        self.refresh_button = QPushButton("刷新")
        self.refresh_button.setToolTip("刷新任务列表")
        self.refresh_button.clicked.connect(self.refresh_task_list)
        toolbar_layout.addWidget(self.refresh_button)
        
        main_layout.addLayout(toolbar_layout)
        
        # 任务表格
        self.tasks_table = QTableWidget()
        self.tasks_table.setColumnCount(7)
        self.tasks_table.setHorizontalHeaderLabels([
            "任务ID", "任务名称", "状态", "优先级", 
            "创建时间", "开始时间", "结束时间"
        ])
        
        # 设置表头
        header = self.tasks_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.ResizeMode.Stretch)
        header.setSectionResizeMode(2, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(4, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(5, QHeaderView.ResizeMode.ResizeToContents)
        header.setSectionResizeMode(6, QHeaderView.ResizeMode.ResizeToContents)
        
        # 设置表格属性
        self.tasks_table.setSelectionBehavior(QTableWidget.SelectionBehavior.SelectRows)
        self.tasks_table.setSelectionMode(QTableWidget.SelectionMode.SingleSelection)
        
        # 连接信号
        self.tasks_table.itemSelectionChanged.connect(self.on_task_selection_changed)
        self.tasks_table.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.tasks_table.customContextMenuRequested.connect(self.show_context_menu)
        
        main_layout.addWidget(self.tasks_table)
        
        # 统计信息
        stats_layout = QHBoxLayout()
        self.total_tasks_label = QLabel("总计: 0 个任务")
        self.pending_tasks_label = QLabel("待执行: 0")
        self.running_tasks_label = QLabel("执行中: 0")
        self.completed_tasks_label = QLabel("已完成: 0")
        self.failed_tasks_label = QLabel("已失败: 0")
        
        stats_layout.addWidget(self.total_tasks_label)
        stats_layout.addWidget(self.pending_tasks_label)
        stats_layout.addWidget(self.running_tasks_label)
        stats_layout.addWidget(self.completed_tasks_label)
        stats_layout.addWidget(self.failed_tasks_label)
        stats_layout.addStretch()
        
        main_layout.addLayout(stats_layout)
        
        # 状态栏
        status_layout = QHBoxLayout()
        self.status_label = QLabel("就绪")
        status_layout.addWidget(self.status_label)
        status_layout.addStretch()
        
        main_layout.addLayout(status_layout)
    
    def on_task_selection_changed(self):
        """当任务选择改变时的处理"""
        has_selection = len(self.tasks_table.selectedItems()) > 0
        
        # 更新按钮状态
        self.edit_task_button.setEnabled(has_selection)
        self.delete_task_button.setEnabled(has_selection)
        self.execute_task_button.setEnabled(has_selection)
        
        # 如果有选中的任务，发送任务选中信号
        if has_selection:
            row = self.tasks_table.currentRow()
            task_id = self.tasks_table.item(row, 0).text()
            task = self._tasks.get(task_id)
            
            if task:
                self.task_selected.emit(task)
    
    def show_context_menu(self, position):
        """显示上下文菜单"""
        item = self.tasks_table.itemAt(position)
        if not item:
            return
        
        row = item.row()
        task_id = self.tasks_table.item(row, 0).text()
        task = self._tasks.get(task_id)
        
        if not task:
            return
        
        # 创建上下文菜单
        menu = QMenu()
        
        # 编辑任务
        edit_action = QAction("编辑任务")
        edit_action.triggered.connect(self.edit_selected_task)
        menu.addAction(edit_action)
        
        # 执行任务
        execute_action = QAction("执行任务")
        execute_action.triggered.connect(self.execute_selected_task)
        execute_action.setEnabled(task.status != "执行中")
        menu.addAction(execute_action)
        
        # 暂停任务（如果任务正在执行）
        is_running = (hasattr(task.status, 'value') and task.status.value == "执行中") or task.status == "执行中"
        if is_running:
            pause_action = QAction("暂停任务")
            pause_action.triggered.connect(lambda: self._pause_task(task_id))
            menu.addAction(pause_action)
        
        # 删除任务
        delete_action = QAction("删除任务")
        delete_action.triggered.connect(self.delete_selected_task)
        menu.addAction(delete_action)
        
        # 查看详情
        details_action = QAction("查看详情")
        details_action.triggered.connect(lambda: self._show_task_details(task_id))
        menu.addAction(details_action)
        
        # 显示菜单
        menu.exec(self.tasks_table.viewport().mapToGlobal(position))
    
    def add_new_task(self):
        """添加新任务"""
        # 在实际应用中，这里应该打开一个对话框让用户输入任务信息
        # 这里我们简化处理，创建一个示例任务
        
        try:
            # 创建一个示例任务
            task_name = f"示例任务_{int(time.time())}"
            # 定义一个示例动作函数
            def sample_action():
                import time
                print(f"执行示例任务: {task_name}")
                time.sleep(1)  # 模拟任务执行
                return f"任务 {task_name} 执行成功"
                
            task = Task(
                name=task_name,
                action=sample_action,  # 提供必需的action参数
                description="这是一个新创建的任务",
                timeout=300
            )
            
            # 添加任务
            self.add_task(task)
            
            # 更新状态
            self.status_label.setText(f"已添加任务: {task_name}")
            
        except Exception as e:
            logger.error(f"添加任务失败: {e}")
            QMessageBox.critical(self, "错误", f"添加任务失败: {str(e)}")
    
    def add_task(self, task):
        """添加任务到管理器"""
        # 添加到任务字典
        self._tasks[task.id] = task
        
        # 更新表格
        self._update_table()
        
        # 发送信号
        self.task_added.emit(task)
        
        logger.info(f"任务已添加: {task.name} (ID: {task.id})")
    
    def edit_selected_task(self):
        """编辑选中的任务"""
        row = self.tasks_table.currentRow()
        if row < 0:
            QMessageBox.warning(self, "警告", "请先选择要编辑的任务")
            return
        
        task_id = self.tasks_table.item(row, 0).text()
        task = self._tasks.get(task_id)
        
        if task:
            # 检查任务状态，如果任务正在运行，不允许编辑
            if task.status == TaskStatus.RUNNING:
                QMessageBox.warning(
                    self, 
                    "警告", 
                    "无法编辑正在运行的任务，请等待任务完成或停止任务后再尝试"
                )
                return
            
            # 创建并显示编辑对话框
            dialog = TaskEditDialog(task, self)
            if dialog.exec_() == QDialog.Accepted:
                # 获取更新后的数据
                updated_data = dialog.get_updated_task_data()
                
                # 验证输入
                if not updated_data['name'].strip():
                    QMessageBox.warning(self, "警告", "任务名称不能为空")
                    return
                
                # 更新任务属性
                old_name = task.name
                task.name = updated_data['name'].strip()
                task.description = updated_data['description'].strip()
                task.timeout = updated_data['timeout']
                
                # 更新表格
                self._update_table()
                
                # 记录日志
                logger.info(f"任务已更新: {old_name} -> {task.name} (ID: {task.id})")
                
                # 显示成功消息
                QMessageBox.information(
                    self, 
                    "成功", 
                    f"任务 '{task.name}' 已成功更新"
                )
    
    def delete_selected_task(self):
        """删除选中的任务"""
        row = self.tasks_table.currentRow()
        if row < 0:
            return
        
        task_id = self.tasks_table.item(row, 0).text()
        task = self._tasks.get(task_id)
        
        if task:
            # 确认删除
            reply = QMessageBox.question(
                self, 
                "确认删除", 
                f"确定要删除任务 '{task.name}' 吗？",
                QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No
            )
            
            if reply == QMessageBox.StandardButton.Yes:
                self.remove_task(task_id)
    
    def remove_task(self, task_id):
        """从管理器中移除任务"""
        if task_id in self._tasks:
            task_name = self._tasks[task_id].name
            del self._tasks[task_id]
            
            # 更新表格
            self._update_table()
            
            # 发送信号
            self.task_removed.emit(task_id)
            
            # 更新状态
            self.status_label.setText(f"已删除任务: {task_name}")
            
            logger.info(f"任务已删除: {task_name} (ID: {task_id})")
    
    def execute_selected_task(self):
        """执行选中的任务"""
        row = self.tasks_table.currentRow()
        if row < 0:
            return
        
        task_id = self.tasks_table.item(row, 0).text()
        task = self._tasks.get(task_id)
        
        # 检查任务是否不是执行状态
        is_not_running = (task and 
                         not (hasattr(task.status, 'value') and task.status.value == "执行中") and 
                         task.status != "执行中")
        
        if is_not_running:
            # 发送任务执行请求
            self.task_execution_requested.emit(task_id)
            
            # 更新状态
            self.status_label.setText(f"请求执行任务: {task.name}")
            
            logger.info(f"请求执行任务: {task.name} (ID: {task_id})")
    
    def _pause_task(self, task_id):
        """暂停任务"""
        task = self._tasks.get(task_id)
        if task:
            # 在实际应用中，这里应该调用任务的暂停方法
            logger.info(f"请求暂停任务: {task.name} (ID: {task_id})")
            self.status_label.setText(f"请求暂停任务: {task.name}")
    
    def _show_task_details(self, task_id):
        """显示任务详情"""
        task = self._tasks.get(task_id)
        if task:
            # 在实际应用中，这里应该显示一个详细信息对话框
            # 格式化时间
            def format_time(timestamp):
                if not timestamp:
                    return "N/A"
                import datetime
                if isinstance(timestamp, (int, float)):
                    return datetime.datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")
                return str(timestamp)
            
            # 状态文本
            status_text = task.status.value if hasattr(task.status, 'value') else str(task.status)
            
            details = (
                f"任务ID: {task.id}\n"
                f"任务名称: {task.name}\n"
                f"描述: {task.description}\n"
                f"状态: {status_text}\n"
                f"优先级: {getattr(task, 'priority', 'medium')}\n"
                f"超时: {task.timeout}秒\n"
                f"创建时间: {format_time(getattr(task, 'created_at', None))}\n"
                f"开始时间: {format_time(getattr(task, 'start_time', None))}\n"
                f"结束时间: {format_time(getattr(task, 'end_time', None))}\n"
                f"执行次数: {getattr(task, 'execution_count', 0)}\n"
                f"重试次数: {getattr(task, 'retry_count', 0)}"
            )
            
            QMessageBox.information(
                self, 
                f"任务详情 - {task.name}", 
                details
            )
    
    def filter_tasks(self, filter_text):
        """筛选任务"""
        self._update_table(filter_text)
    
    def refresh_task_list(self):
        """刷新任务列表"""
        current_filter = self.filter_combo.currentText()
        self._update_table(current_filter)
        self.status_label.setText("任务列表已刷新")
    
    def _update_table(self, filter_text="全部任务"):
        """更新任务表格"""
        # 清空表格
        self.tasks_table.setRowCount(0)
        
        # 过滤任务
        filtered_tasks = self._get_filtered_tasks(filter_text)
        
        # 添加任务到表格
        for task in filtered_tasks.values():
            self._add_task_to_table(task)
        
        # 更新统计信息
        self._update_stats()
    
    def _get_filtered_tasks(self, filter_text):
        """获取过滤后的任务"""
        if filter_text == "全部任务":
            return self._tasks
        
        filtered = {}
        for task_id, task in self._tasks.items():
            # 获取任务状态文本
            task_status_text = task.status.value if hasattr(task.status, 'value') else str(task.status)
            
            # 映射枚举状态到过滤器文本
            status_mapping = {
                "待执行": "未开始",
                "执行中": "执行中",
                "成功": "已完成",
                "失败": "已失败"
            }
            
            # 获取映射后的状态
            mapped_status = status_mapping.get(task_status_text, task_status_text)
            
            if mapped_status == filter_text:
                filtered[task_id] = task
        
        return filtered
    
    def _add_task_to_table(self, task):
        """将任务添加到表格中"""
        row_position = self.tasks_table.rowCount()
        self.tasks_table.insertRow(row_position)
        
        # 创建单元格
        task_id_item = QTableWidgetItem(task.id)
        task_id_item.setFlags(task_id_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
        
        name_item = QTableWidgetItem(task.name)
        name_item.setFlags(name_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
        
        # 从TaskStatus枚举获取显示名称
        status_text = task.status.value if hasattr(task.status, 'value') else str(task.status)
        status_item = QTableWidgetItem(status_text)
        status_item.setFlags(status_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
        self._set_status_item_style(status_item, status_text)
        
        # 优先级默认为中
        priority_text = getattr(task, 'priority', 'medium')
        priority_item = QTableWidgetItem(priority_text)
        priority_item.setFlags(priority_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
        
        # 创建时间使用当前时间
        from datetime import datetime
        created_at_text = getattr(task, 'created_at', datetime.now()).strftime("%Y-%m-%d %H:%M:%S")
        created_at_item = QTableWidgetItem(created_at_text)
        created_at_item.setFlags(created_at_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
        
        # 开始时间
        if hasattr(task, 'start_time') and task.start_time:
            import datetime
            started_at_text = datetime.datetime.fromtimestamp(task.start_time).strftime("%Y-%m-%d %H:%M:%S")
        else:
            started_at_text = "N/A"
        started_at_item = QTableWidgetItem(started_at_text)
        started_at_item.setFlags(started_at_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
        
        # 结束时间
        if hasattr(task, 'end_time') and task.end_time:
            import datetime
            ended_at_text = datetime.datetime.fromtimestamp(task.end_time).strftime("%Y-%m-%d %H:%M:%S")
        else:
            ended_at_text = "N/A"
        ended_at_item = QTableWidgetItem(ended_at_text)
        ended_at_item.setFlags(ended_at_item.flags() & ~Qt.ItemFlag.ItemIsEditable)
        
        # 设置单元格
        self.tasks_table.setItem(row_position, 0, task_id_item)
        self.tasks_table.setItem(row_position, 1, name_item)
        self.tasks_table.setItem(row_position, 2, status_item)
        self.tasks_table.setItem(row_position, 3, priority_item)
        self.tasks_table.setItem(row_position, 4, created_at_item)
        self.tasks_table.setItem(row_position, 5, started_at_item)
        self.tasks_table.setItem(row_position, 6, ended_at_item)
    
    def _set_status_item_style(self, item, status):
        """设置状态单元格样式"""
        if status == "已完成":
            item.setBackground(QColor("#d4edda"))
            item.setForeground(QColor("#155724"))
        elif status == "执行中":
            item.setBackground(QColor("#d1ecf1"))
            item.setForeground(QColor("#0c5460"))
        elif status == "已失败":
            item.setBackground(QColor("#f8d7da"))
            item.setForeground(QColor("#721c24"))
        elif status == "已暂停":
            item.setBackground(QColor("#fff3cd"))
            item.setForeground(QColor("#856404"))
        elif status == "未开始":
            item.setBackground(QColor("#e2e3e5"))
            item.setForeground(QColor("#495057"))
    
    def _update_stats(self):
        """更新统计信息"""
        total = len(self._tasks)
        # 适配TaskStatus枚举
        pending = sum(1 for task in self._tasks.values() 
                     if (hasattr(task.status, 'value') and task.status.value == "待执行") or task.status == "未开始")
        running = sum(1 for task in self._tasks.values() 
                     if (hasattr(task.status, 'value') and task.status.value == "执行中") or task.status == "执行中")
        completed = sum(1 for task in self._tasks.values() 
                       if (hasattr(task.status, 'value') and task.status.value == "成功") or task.status == "已完成")
        failed = sum(1 for task in self._tasks.values() 
                    if (hasattr(task.status, 'value') and task.status.value == "失败") or task.status == "已失败")
        
        self.total_tasks_label.setText(f"总计: {total} 个任务")
        self.pending_tasks_label.setText(f"待执行: {pending}")
        self.running_tasks_label.setText(f"执行中: {running}")
        self.completed_tasks_label.setText(f"已完成: {completed}")
        self.failed_tasks_label.setText(f"已失败: {failed}")
    
    def update_task_status(self, task_id, status, started_at=None, ended_at=None):
        """更新任务状态"""
        if task_id in self._tasks:
            task = self._tasks[task_id]
            
            # 映射状态文本到TaskStatus枚举
            status_mapping = {
                "未开始": TaskStatus.PENDING,
                "执行中": TaskStatus.RUNNING,
                "已完成": TaskStatus.SUCCESS,
                "已失败": TaskStatus.FAILED,
                "已暂停": TaskStatus.PENDING  # 暂停状态映射到待执行
            }
            
            # 设置任务状态
            task.status = status_mapping.get(status, status)
            
            # 更新时间属性
            if started_at:
                task.start_time = started_at
            if ended_at:
                task.end_time = ended_at
            
            # 刷新表格
            self.refresh_task_list()
    
    def get_task(self, task_id):
        """获取任务"""
        return self._tasks.get(task_id)
    
    def get_all_tasks(self):
        """获取所有任务"""
        return list(self._tasks.values())